package org.evil.deus.rss.parser;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;

public class ItemsParser {
	private static final String TAG_CHANNEL = "channel";
	private static final String TAG_ITEM = "item";
	private static final String TAG_TITLE = "title";
	private static final String TAG_LINK = "link";
	private static final String TAG_CATEGORY = "category";
	private static final String TAG_AUTHOR = "author";
	private static final String TAG_PUBDATE = "pubDate";
	private static final String TAG_DESCRIPTION = "description";
	private static final String TAG_URL = "url";
	private static final String TAG_LANGUAGE = "language";
	
	public class BaseItem {
		protected String title = null;
		protected String link = null;
		protected String description = null;
		
		public String getTitle() {
			return title;
		}
		public String getLink() {
			return link;
		}
		public String getDescription() {
			return description;
		}
	}
	
	public class Item extends BaseItem {
		private String category = null;
		private String author = null;
		private long pubDate = 0;
		
		public String getCategory() {
			return category;
		}
		public String getAuthor() {
			return author;
		}
		public long getPubDate() {
			return pubDate;
		}
	} 
	
	public class Channel extends BaseItem {
		private String url = null;
		private String language = null;
		
		public String getUrl() {
			return url;
		}
		public String getLanguage() {
			return language;
		}
	}
	
	private ArrayList<Item> items = new ArrayList<Item>();
	private ArrayList<Channel> channels = new ArrayList<Channel>();
	
	public Channel [] getChannels() {
		return channels.toArray(new Channel [0]);
	}
	
	public Item [] getItems() {
		return items.toArray(new Item[0]);
	}
	
	public boolean parse(InputStream in) {
		try {
			XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
			parser.setInput(in, "cp1251");
			String tagName = null;
			String tagValue = null;
			String tagParrent = null;
			Item item = null;
			Channel channel = null;
			int eventType = parser.getEventType();
			while (XmlPullParser.END_DOCUMENT != eventType) {
				switch (eventType) {
					case XmlPullParser.START_TAG:
						tagName = parser.getName();
						if (TAG_ITEM.equals(tagName)) {
							item = new Item();
							tagParrent = TAG_ITEM;
						} else if (TAG_CHANNEL.equals(tagName)) {
							channel = new Channel();
							tagParrent = TAG_CHANNEL;
						}
						tagValue = null;
						break;
					case XmlPullParser.TEXT:
						tagValue = parser.getText();
						break;
					case XmlPullParser.END_TAG:
						tagName = parser.getName();
						if (TAG_TITLE.equals(tagName)) {
							if (TAG_ITEM.equals(tagParrent)) {
								item.title = tagValue;
							} else {
								channel.title = tagValue;
							}
						} else if (TAG_LINK.equals(tagName)) {
							if (TAG_ITEM.equals(tagParrent)) {
								item.link = tagValue;
							} else {
								channel.link = tagValue;
							}
						} else if (TAG_CATEGORY.equals(tagName)) {
							item.category = tagValue;
						} else if (TAG_AUTHOR.equals(tagName)) {
							item.author = tagValue;
						} else if (TAG_PUBDATE.equals(tagName)) {
							item.pubDate = Date.parse(tagValue);
						} else if (TAG_DESCRIPTION.equals(tagName)) {
							if (TAG_ITEM.equals(tagParrent)) {
								item.description = tagValue;
							} else {
								channel.description = tagValue;
							}
						} else if (TAG_ITEM.equals(tagName)) {
							items.add(item);
						} else if (TAG_CHANNEL.equals(tagName)) {
							channels.add(channel);
						} else if (TAG_URL.equals(tagName)) {
							channel.url = tagValue;
						} else if (TAG_LANGUAGE.equals(tagName)) {
							channel.language = tagValue;
						}
						break;
				}
				eventType = parser.next();
			}
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}
}
